home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xlock / swarm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-09  |  5.4 KB  |  203 lines

  1. #ifndef lint
  2. static char sccsid[] = "@(#)swarm.c    1.5 91/05/24 XLOCK";
  3. #endif
  4. /*-
  5.  * swarm.c - swarm of bees for xlock, the X Window System lockscreen.
  6.  *
  7.  * Copyright (c) 1991 by Patrick J. Naughton.
  8.  *
  9.  * Revision History:
  10.  * 31-Aug-90: Adapted from xswarm by Jeff Butterworth. (butterwo@ncsc.org)
  11.  */
  12.  
  13. #include "xlock.h"
  14.  
  15. #define TIMES    4        /* number of time positions recorded */
  16. #define BEEACC    3        /* acceleration of bees */
  17. #define WASPACC 5        /* maximum acceleration of wasp */
  18. #define BEEVEL    11        /* maximum bee velocity */
  19. #define WASPVEL 12        /* maximum wasp velocity */
  20. #define BORDER    50        /* wasp won't go closer than this to the edge */
  21.  
  22. /* Macros */
  23. #define X(t,b)    (sp->x[(t)*sp->beecount+(b)])
  24. #define Y(t,b)    (sp->y[(t)*sp->beecount+(b)])
  25. #define RAND(v)    ((random()%(v))-((v)/2))    /* random number around 0 */
  26.  
  27. typedef struct {
  28.     int         pix;
  29.     long        startTime;
  30.     int         width;
  31.     int         height;
  32.     int         beecount;    /* number of bees */
  33.     XSegment   *segs;        /* bee lines */
  34.     XSegment   *old_segs;    /* old bee lines */
  35.     short      *x;
  36.     short      *y;        /* bee positions x[time][bee#] */
  37.     short      *xv;
  38.     short      *yv;        /* bee velocities xv[bee#] */
  39.     short       wx[3];
  40.     short       wy[3];
  41.     short       wxv;
  42.     short       wyv;
  43. }           swarmstruct;
  44.  
  45. static swarmstruct swarms[MAXSCREENS];
  46.  
  47. void
  48. initswarm(win)
  49.     Window      win;
  50. {
  51.     XWindowAttributes xgwa;
  52.     swarmstruct *sp = &swarms[screen];
  53.     int         b;
  54.  
  55.     sp->startTime = seconds();
  56.     sp->beecount = batchcount;
  57.  
  58.     XGetWindowAttributes(dsp, win, &xgwa);
  59.     sp->width = xgwa.width;
  60.     sp->height = xgwa.height;
  61.  
  62.     /* Clear the background. */
  63.     XSetForeground(dsp, Scr[screen].gc, BlackPixel(dsp, screen));
  64.     XFillRectangle(dsp, win, Scr[screen].gc, 0, 0, sp->width, sp->height);
  65.  
  66.     /* Allocate memory. */
  67.  
  68.     if (!sp->segs) {
  69.     sp->segs = (XSegment *) malloc(sizeof(XSegment) * sp->beecount);
  70.     sp->old_segs = (XSegment *) malloc(sizeof(XSegment) * sp->beecount);
  71.     sp->x = (short *) malloc(sizeof(short) * sp->beecount * TIMES);
  72.     sp->y = (short *) malloc(sizeof(short) * sp->beecount * TIMES);
  73.     sp->xv = (short *) malloc(sizeof(short) * sp->beecount);
  74.     sp->yv = (short *) malloc(sizeof(short) * sp->beecount);
  75.     }
  76.     /* Initialize point positions, velocities, etc. */
  77.  
  78.     /* wasp */
  79.     sp->wx[0] = BORDER + random() % (sp->width - 2 * BORDER);
  80.     sp->wy[0] = BORDER + random() % (sp->height - 2 * BORDER);
  81.     sp->wx[1] = sp->wx[0];
  82.     sp->wy[1] = sp->wy[0];
  83.     sp->wxv = 0;
  84.     sp->wyv = 0;
  85.  
  86.     /* bees */
  87.     for (b = 0; b < sp->beecount; b++) {
  88.     X(0, b) = random() % sp->width;
  89.     X(1, b) = X(0, b);
  90.     Y(0, b) = random() % sp->height;
  91.     Y(1, b) = Y(0, b);
  92.     sp->xv[b] = RAND(7);
  93.     sp->yv[b] = RAND(7);
  94.     }
  95. }
  96.  
  97.  
  98.  
  99. void
  100. drawswarm(win)
  101.     Window      win;
  102. {
  103.     swarmstruct *sp = &swarms[screen];
  104.     int         b;
  105.  
  106.     /* <=- Wasp -=> */
  107.     /* Age the arrays. */
  108.     sp->wx[2] = sp->wx[1];
  109.     sp->wx[1] = sp->wx[0];
  110.     sp->wy[2] = sp->wy[1];
  111.     sp->wy[1] = sp->wy[0];
  112.     /* Accelerate */
  113.     sp->wxv += RAND(WASPACC);
  114.     sp->wyv += RAND(WASPACC);
  115.  
  116.     /* Speed Limit Checks */
  117.     if (sp->wxv > WASPVEL)
  118.     sp->wxv = WASPVEL;
  119.     if (sp->wxv < -WASPVEL)
  120.     sp->wxv = -WASPVEL;
  121.     if (sp->wyv > WASPVEL)
  122.     sp->wyv = WASPVEL;
  123.     if (sp->wyv < -WASPVEL)
  124.     sp->wyv = -WASPVEL;
  125.  
  126.     /* Move */
  127.     sp->wx[0] = sp->wx[1] + sp->wxv;
  128.     sp->wy[0] = sp->wy[1] + sp->wyv;
  129.  
  130.     /* Bounce Checks */
  131.     if ((sp->wx[0] < BORDER) || (sp->wx[0] > sp->width - BORDER - 1)) {
  132.     sp->wxv = -sp->wxv;
  133.     sp->wx[0] += sp->wxv;
  134.     }
  135.     if ((sp->wy[0] < BORDER) || (sp->wy[0] > sp->height - BORDER - 1)) {
  136.     sp->wyv = -sp->wyv;
  137.     sp->wy[0] += sp->wyv;
  138.     }
  139.     /* Don't let things settle down. */
  140.     sp->xv[random() % sp->beecount] += RAND(3);
  141.     sp->yv[random() % sp->beecount] += RAND(3);
  142.  
  143.     /* <=- Bees -=> */
  144.     for (b = 0; b < sp->beecount; b++) {
  145.     int         distance,
  146.                 dx,
  147.                 dy;
  148.     /* Age the arrays. */
  149.     X(2, b) = X(1, b);
  150.     X(1, b) = X(0, b);
  151.     Y(2, b) = Y(1, b);
  152.     Y(1, b) = Y(0, b);
  153.  
  154.     /* Accelerate */
  155.     dx = sp->wx[1] - X(1, b);
  156.     dy = sp->wy[1] - Y(1, b);
  157.     distance = abs(dx) + abs(dy);    /* approximation */
  158.     if (distance == 0)
  159.         distance = 1;
  160.     sp->xv[b] += (dx * BEEACC) / distance;
  161.     sp->yv[b] += (dy * BEEACC) / distance;
  162.  
  163.     /* Speed Limit Checks */
  164.     if (sp->xv[b] > BEEVEL)
  165.         sp->xv[b] = BEEVEL;
  166.     if (sp->xv[b] < -BEEVEL)
  167.         sp->xv[b] = -BEEVEL;
  168.     if (sp->yv[b] > BEEVEL)
  169.         sp->yv[b] = BEEVEL;
  170.     if (sp->yv[b] < -BEEVEL)
  171.         sp->yv[b] = -BEEVEL;
  172.  
  173.     /* Move */
  174.     X(0, b) = X(1, b) + sp->xv[b];
  175.     Y(0, b) = Y(1, b) + sp->yv[b];
  176.  
  177.     /* Fill the segment lists. */
  178.     sp->segs[b].x1 = X(0, b);
  179.     sp->segs[b].y1 = Y(0, b);
  180.     sp->segs[b].x2 = X(1, b);
  181.     sp->segs[b].y2 = Y(1, b);
  182.     sp->old_segs[b].x1 = X(1, b);
  183.     sp->old_segs[b].y1 = Y(1, b);
  184.     sp->old_segs[b].x2 = X(2, b);
  185.     sp->old_segs[b].y2 = Y(2, b);
  186.     }
  187.  
  188.     XSetForeground(dsp, Scr[screen].gc, BlackPixel(dsp, screen));
  189.     XDrawLine(dsp, win, Scr[screen].gc,
  190.           sp->wx[1], sp->wy[1], sp->wx[2], sp->wy[2]);
  191.     XDrawSegments(dsp, win, Scr[screen].gc, sp->old_segs, sp->beecount);
  192.  
  193.     XSetForeground(dsp, Scr[screen].gc, WhitePixel(dsp, screen));
  194.     XDrawLine(dsp, win, Scr[screen].gc,
  195.           sp->wx[0], sp->wy[0], sp->wx[1], sp->wy[1]);
  196.     if (!mono && Scr[screen].npixels > 2) {
  197.     XSetForeground(dsp, Scr[screen].gc, Scr[screen].pixels[sp->pix]);
  198.     if (++sp->pix >= Scr[screen].npixels)
  199.         sp->pix = 0;
  200.     }
  201.     XDrawSegments(dsp, win, Scr[screen].gc, sp->segs, sp->beecount);
  202. }
  203.